<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>图片上传测试</title>
    <style>
        form {
            width: 520px;
            margin: 100px auto;
            border: 1px solid red;
            text-align: center;
        }

        form>div {
            margin-bottom: 20px;
        }
        canvas {
            display: block;
        }

        #up-canvas {
            position: absolute;
            left: 0;
            top: 0;
        }

        #container {
            margin: 10px;
            position: relative;
            overflow: hidden;
            border: 1px solid gainsboro;
        }

        .drag {
            width: 8px;
            height: 8px;
            position: absolute;
            cursor: nw-resize;
            background-color: red;
        }

        #result-img {
            display: inline-block;
        }
    </style>
</head>

<body>
    <form id="my-form" action="#" method="post" enctype="multipart/form-data">
        <!-- <div>
            <label>上传单张图片:</label>
            <input type="file" onchange="previewFile()">
            <br>
            <div id="container">
                <canvas id="canvas"></canvas>
                <canvas id="up-canvas"></canvas>
                <div class="drag"></div>
            </div>
            <p>裁剪结果：</p>
            <canvas id="result-img"></canvas>
            <p>图片大小：
                <span id="cut-size"></span>
            </p>
        </div> -->
        <div>
            <label>上传多张图片:</label>
            <input id="browse" type="file" onchange="previewFiles()" multiple>
            <div id="preview"></div>
        </div>
        <button id="submit" type="button">上传</button>
        <button id="remove" type="button">删除</button>
    </form>
</body>

<script src="https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js"></script>
<script>
    // 矩形框起始点
    var startPoint = [0, 0];
    // 鼠标拖拽起始点
    var moveStartPoint = [];
    // 矩形框大小
    var size = [100, 100];
    // 限制大小
    var limitSize = 70;
    // 拖拽点大小
    var dragPoint = 8;
    // 状态量
    var isPush = false;
    var inRect = false;
    var isDragPush = false;
    // 源图片数据
    var sourceImg;
    // 临时变量
    var tempX, tempY, sizeW, sizeH;

    var input = document.querySelector('input[type=file]');
    var container = document.getElementById('container');
    var drag = document.querySelector('div.drag');
    var submitBtn = document.getElementById('submit');
    var cutSize = document.getElementById('cut-size');
    var resultImg = document.getElementById('result-img');
    var canvas = document.getElementById('canvas');
    var upCanvas = document.getElementById('up-canvas');

    var context = canvas.getContext('2d');
    canvas.width = 500;
    canvas.height = 400;

    var upContext = upCanvas.getContext('2d');
    upCanvas.width = 500;
    upCanvas.height = 400;

    var resultContext = resultImg.getContext('2d');
    resultImg.width = limitSize;
    resultImg.height = limitSize;


    // 程序入口
    $(function () {
        upCanvas.addEventListener('mousedown', function (e) {
            var clientX = e.clientX - (upCanvas.offsetLeft + container.offsetLeft);
            var clientY = e.clientY - (upCanvas.offsetTop + container.offsetTop);
            if (clientX > startPoint[0] && clientX < startPoint[0] + size[0] && clientY > startPoint[1] && clientY < startPoint[1] + size[1]) {
                inRect = true;
                moveStartPoint = [clientX, clientY];
            }
            isPush = true;
        });

        upCanvas.addEventListener('mousemove', function (e) {
            var currentX = e.clientX - (upCanvas.offsetLeft + container.offsetLeft);
            var currentY = e.clientY - (upCanvas.offsetTop + container.offsetTop);
            if (isPush && inRect) {
                move = [currentX - moveStartPoint[0], currentY - moveStartPoint[1]];
                drag.style.left = (startPoint[0] + move[0] + size[0] - dragPoint/2) + 'px';
                drag.style.top = (startPoint[1] + move[1] + size[1] - dragPoint/2) + 'px';
                tempX = startPoint[0] + move[0];
                tempY = startPoint[1] + move[1];
                drawRect(tempX, tempY, size[0], size[1]);
            }
            if (isDragPush) {
                sizeW = currentX - startPoint[0];
                sizeH = currentY - startPoint[1];
                drag.style.left = (currentX - dragPoint/2) + 'px';
                drag.style.top = (currentY - dragPoint/2) + 'px';
                if (sizeW < limitSize || sizeH < limitSize) {
                    if (sizeW < limitSize) {
                        sizeW = limitSize;
                        drag.style.left = (startPoint[0] + limitSize - dragPoint/2) + 'px';
                    } else {
                        sizeH = limitSize;
                        drag.style.top = (startPoint[1] + limitSize - dragPoint/2) + 'px';
                    }
                    isDragPush = false;
                    size = [sizeW, sizeH];
                }
                drawRect(startPoint[0], startPoint[1], sizeW, sizeH);
            }
        });

        upCanvas.addEventListener('mouseup', function (e) {
            if (tempX && tempY) {
                startPoint = [tempX, tempY];
            }
            isPush = false;
            inRect = false;
            saveImg(startPoint[0], startPoint[1], size[0], size[1]);
        });

        drag.addEventListener('mousedown', function (e) {
            isDragPush = true;
        });

        drag.addEventListener('mouseup', function (e) {
            if (sizeW && sizeH) {
                size = [sizeW, sizeH];
            }
            isDragPush = false;
            saveImg(startPoint[0], startPoint[1], size[0], size[1]);
        });

        // 提交后台
        submitBtn.addEventListener('click', function (e) {
            // 转成blob格式，toDataURL方法可以将画布转成base64格式图片数据，两个方法都可用于图片压缩
            resultImg.toBlob(function (blob) {
                // 如果参数为from元素，form要添加enctype="multipart/form-data"属性
                var formData = new FormData();
                formData.append('sheng', blob);
                $.ajax({
                    url: '/test/upload',
                    type: 'post',
                    data: formData,
                    processData: false,  // 默认情况下会将data转成查询字符串，因为data值是FormData对象，不需要对数据做处理，通过设为false来避免
                    contentType: false,  // 如果是由<form>表单构造的FormData对象且已声明了属性，则设为false
                    success: function (res) {
                        console.log(res);
                    },
                    error: function (err) {
                        console.log(err);
                    }
                });
            }, 'image/jpeg', 0.5);
        });
    });


    // 画矩形
    function drawRect(x, y, width, height) {
        upContext.clearRect(0, 0, upCanvas.width, upCanvas.height);

        upContext.beginPath();
        upContext.fillStyle = 'rgba(0, 0, 0, 0.4)';
        upContext.fillRect(0, 0, upCanvas.width, upCanvas.height);
        upContext.drawImage(sourceImg, x, y, width, height, x, y, width, height);
        upContext.strokeStyle = 'red';
        upContext.strokeRect(x, y, width, height);
    }

    // 存储裁剪图片数据
    function saveImg(x, y, width, height) {
        var imageData = context.getImageData(x, y, width, height);
        resultImg.width = width;
        resultImg.height = height;
        resultContext.putImageData(imageData, 0, 0);
        cutSize.innerText = `${width} * ${height}`;
    }

    // 图片上传预览（单个）
    function previewFile() {
        if (input.files && input.files[0]) {
            var file = input.files[0];
            var reader = new FileReader();
            reader.readAsDataURL(file);
            context.clearRect(0, 0, canvas.width, canvas.height);
            reader.addEventListener("load", function () {
                sourceImg = new Image();
                sourceImg.src = reader.result;
                sourceImg.onload = function () {
                    context.drawImage(sourceImg, 0, 0);
                    drawRect(startPoint[0], startPoint[1], size[0], size[1]);
                    drag.style.left = startPoint[0] + (size[0] - dragPoint/2) + 'px';
                    drag.style.top = startPoint[1] + (size[1] - dragPoint/2) + 'px';
                }
            }, false);
        } else {
            input.select();
            input.blur();
            var src = document.selection.createRange().text;
            preview.src = src;
        }
    }

    // 图片上传预览（多个）
    function previewFiles() {
        var preview = document.querySelector('#preview');
        var files = document.querySelector('input[type=file]').files;

        function readAndPreview(file) {
            // 确保 `file.name` 符合我们要求的扩展名
            if (/\.(jpe?g|png|gif)$/i.test(file.name)) {
                var reader = new FileReader();
                reader.addEventListener("load", function () {
                    var image = new Image();
                    image.height = 100;
                    image.title = file.name;
                    image.src = this.result;
                    preview.appendChild(image);
                }, false);
                reader.readAsDataURL(file);
            }
        }

        if (files) {
            [].forEach.call(files, readAndPreview);
        }
    }
</script>

</html>